package com.zy.test.service.impl;

import com.google.common.collect.Lists;
import com.zy.test.service.MonitorService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.cloud.sleuth.instrument.async.LazyTraceThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author MissZhou
 */
@Service
public class MonitorServiceImpl implements MonitorService {

    private final LazyTraceThreadPoolTaskExecutor monitorThreadPoolTaskExecutor;

    private static final Logger logger = LoggerFactory.getLogger(MonitorServiceImpl.class);

    @Autowired
    public MonitorServiceImpl (@Qualifier("monitorThreadPoolTaskExecutor") LazyTraceThreadPoolTaskExecutor monitorThreadPoolTaskExecutor){
        this.monitorThreadPoolTaskExecutor = monitorThreadPoolTaskExecutor;
    }

    /**
     * 监控数据异常
     */
    @Override
    public void moniter() {
        //1、查询数据库获取数据
        List<String> dataList = initDataList();
        //2、进行数据分组
        List<List<String>> partitionList = Lists.partition(dataList, 1000);
        //计数器的值就是总得分组数量，每个分组执行完后计数器的值则会减一，直到值为0，主线程才会继续执行
        CountDownLatch countDownLatch = new CountDownLatch(partitionList.size());
        //异常数量
        AtomicInteger atomicInteger = new AtomicInteger();
        //3、循环子分组进行处理
        for (List<String> groupList : partitionList) {
            //4、子小组使用多线程处理
            // todo 此处空指针异常
            monitorThreadPoolTaskExecutor.execute(() -> {
                //5、统计异常数据
                try {
                    handle(groupList,atomicInteger);
                }catch (Exception e){
                    logger.error("统计异常数据报错,{}",e);
                }finally {
                    //计数器减一
                    countDownLatch.countDown();
                }
            });
        }
        //阻塞主线程
        try {
            //根据项目业务执行时间来定
            countDownLatch.await(5, TimeUnit.MINUTES);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        monitorThreadPoolTaskExecutor.shutdown();
        //6、操作日志记录或发送邮件等业务

        //简单模拟打印一下
        logger.error("统计异常数量，{}",atomicInteger.get());
    }

    private void handle(List<String> groupList, AtomicInteger atomicInteger) {
        //此处模拟大于九万为异常数据，实际根据业务需求判断
        for (String data : groupList) {
            if (Integer.parseInt(data) > 90000) {
                //异常数量+1
                atomicInteger.incrementAndGet();
            }
        }

    }

    private List<String> initDataList() {
        List<String> result = new ArrayList<>();
        for (int i = 1; i <= 100000; i++) {
            result.add(String.valueOf(i));
        }
        return result;
    }
}
